﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.Net.Mail;
using System.IO;
using System.Net.Mime;
using Marbles.Core.Connectors;
using Marbles.Core.Authentication;
using Marbles.Core.Content.Forms;

namespace Marbles.Core.Handlers
{
    public class UserFormHandler : HttpHandlerBase, IHttpHandlerBase
    {

        public void ProcessRequest(HttpContext context)
        {
            DataConnection dbc = new DataConnection();
            DateTime submitdate = DateTime.Now;
            Command cmd = null;
            string responseid = Guid.NewGuid().ToString();
            string userid = string.Empty;
            string formName = context.Request.Form["id"];
            context.Response.ContentType = "text/plain";
            UserForm frm = new UserForm(formName);
            MailMessage msg = null;            
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
            sb.AppendLine("<form>");
            sb.AppendLine("<name>" + context.Server.HtmlEncode(frm.Name) + "</name>");
            sb.AppendLine("<responseid>" + context.Server.HtmlEncode(responseid) + "</responseid>");
            sb.AppendLine("<submitdate>" + submitdate.ToString("r") + "</submitdate>");

            if (AuthenticationProvider != null)
            {
                if (AuthenticationProvider.CurrentToken != null)
                {
                    sb.AppendLine("<user>");
                    sb.AppendLine("<identity>" + context.Server.HtmlEncode(AuthenticationProvider.CurrentToken.UserId) + "</identity>");
                    sb.AppendLine("<username>" + context.Server.HtmlEncode(AuthenticationProvider.CurrentToken.Username) + "</username>");
                    sb.AppendLine("<fullname>" + context.Server.HtmlEncode(AuthenticationProvider.CurrentToken.Fullname) + "</fullname>");
                    sb.AppendLine("<email>" + context.Server.HtmlEncode(AuthenticationProvider.CurrentToken.Email) + "</email>");
                    sb.AppendLine("(</user>");
                    userid = AuthenticationProvider.CurrentToken.UserId;
                }
            }

            if (frm.StoreInDatabase)
            {
                cmd = new Command("INSERT INTO userformheader (siteid,responseid, userid, formname, clientip, creationdate) VALUES (@siteid, @responseid, @userid, @formname, @clientip, @creationdate)");
                cmd.AddParameter("@responseid", responseid);
                cmd.AddParameter("@userid", userid);
                cmd.AddParameter("@clientip", context.Request.UserHostAddress);
                cmd.AddParameter("@creationdate", submitdate);
                cmd.AddParameter("@siteid", frm.SiteId);
                cmd.AddParameter("@formname", frm.Name);
                dbc.ExecuteCommand(cmd);
            }

            sb.AppendLine("<clientaddress>" + context.Request.UserHostAddress + "</clientaddress>");
            sb.AppendLine("<clientbrowser>" + context.Server.HtmlEncode(context.Request.UserAgent) + "</clientbrowser>");

            if ((!string.IsNullOrEmpty(frm.MailTo)) && (frm.SendEmail))
            {
                msg = CreateMailMessage(true);
                msg.Subject = frm.EmailSubject;
                foreach (string s in frm.MailTo.Split(';'))
                {
                    if (!string.IsNullOrEmpty(s.Trim())) { msg.To.Add(new MailAddress(s.Trim())); }
                }
                msg.Body = "<html><head></head><body style=\"font-family:Verdana, Arial, helvetica, Sans-Serif;font-size:10px;\"><table border=\"1\" rules=\"all\" cellpadding=\"2\" cellspacing=\"0\">";
            }

            sb.AppendLine("<responses>");

            foreach (Question q in frm)
            {
                string value = context.Request.Form[q.Id];
                string value1 = value.Trim();
                sb.AppendLine("<response id=\"" + q.Id + "\">");
                switch (q.QuestionType)
                {
                    case QuestionType.RadioButton:
                    case QuestionType.Checkbox:
                        bool bvalue = false;
                        if (!bool.TryParse(value, out bvalue)) { bvalue = false; }
                        value = bvalue ? "Selected" : "";
                        value1 = value;
                        break;
                    case QuestionType.RadioButtonList:
                    case QuestionType.DropdownList:
                    case QuestionType.Listbox:
                    case QuestionType.CheckboxList:
                    case QuestionType.MultiSelectListbox:
                        string[] args = value.Split('$');
                        value = "";
                        value1 = "";
                        foreach (string s in args)
                        {
                            if (q.Items.ContainsKey(s))
                            {
                                if (!string.IsNullOrEmpty(value)) { value += "<br/>"; value1 += ", "; }
                                value += q.Items[s];
                                value1 += q.Items[s];
                            }
                        }
                        break;
                    case QuestionType.MultiLineTextbox:
                        value = value.Replace("\n", "<br/>");
                        break;
                }

                value1 = value1.Trim();
                sb.AppendLine("<question>" + context.Server.HtmlEncode(q.Text) + "</question>");
                sb.AppendLine("<value>" + context.Server.HtmlEncode(value1) + "</value>");
                if (msg != null)
                {
                    msg.Body += string.Format("<tr><td valign=\"top\">{0}</td><td>&nbsp;</td><td>{1}</td></tr>", q.Text, value);
                }

                sb.AppendLine("</response>");

                if (frm.StoreInDatabase)
                {
                    cmd = new Command("INSERT INTO userformresponses (responseid, questionid, response) VALUES (@responseid, @questionid, @response)");
                    cmd.AddParameter("@responseid", responseid);
                    cmd.AddParameter("@questionid", q.Id);
                    cmd.AddParameter("@response", value1);
                    dbc.ExecuteCommand(cmd);
                }

            }

            sb.AppendLine("</responses>");

            sb.AppendLine("</form>");

            if (msg != null)
            {
                MemoryStream memorystream = new MemoryStream();
                StreamWriter streamwriter = new StreamWriter(memorystream);
                streamwriter.Write(sb.ToString());
                streamwriter.Flush();
                memorystream.Seek(0, SeekOrigin.Begin);
                msg.Attachments.Add(new Attachment(memorystream, "Response.xml", MediaTypeNames.Text.Xml));
                msg.Body += "</table></body></html>";
                Settings.MailSettings.CreateSmtpClient().Send(msg);
                streamwriter.Close();

            }

            context.Response.Write("OK");
            context.Response.Flush();
        }

        public string Verbs
        {
            get { return "POST"; }
        }

        public bool Validate
        {
            get { return false; }
        }

        public string Path
        {
            get { return "UserFormSubmit.axd"; }
        }

        public string Name
        {
            get { return this.GetType().Name; }
        }

        public bool IsReusable
        {
            get { return false; }
        }

        private MailMessage CreateMailMessage(bool html)
        {
            string ipaddress = HttpContext.Current.Request.UserHostAddress;
            MailMessage msg = new MailMessage();
            msg.IsBodyHtml = html;
            msg.Headers.Add("X-Originating-IP", ipaddress);
            msg.Headers.Add("X-Originating-Email", Settings.SettingsManager.UserFormMailAddress);
            msg.Headers.Add("X-Mailer", "MarblesCMS");
            msg.From = new MailAddress(Settings.SettingsManager.UserFormMailAddress);
            return msg;
        }
    }


}